<!--
 * @Author: Dorange.Wang
 * @Date: 2021-07-14 19:41:16
 * @LastEditors: your name
 * @LastEditTime: 2021-07-19 09:25:25
 * @Description: file content
-->
<template>
  <van-popup v-model="show" round position="bottom">
    <van-picker
      :title="options.title"
      show-toolbar
      :columns="columns"
      @confirm="onConfirm"
      @cancel="onCancel"
      @change="onChange"
    />
  </van-popup>
</template>

<script>
import Dayjs from "dayjs";
// 日期类型支持的格式
// const DATE_FORMAT = ["YYYY-MM-DD", "YYYY-MM", "YYYY", "YYYY-MM-DD HH:mm"];
// 时间类型支持的格式
// const TIME_FORMAT = ["HH:mm:ss", "HH:mm"];
const DEFAULT_OPTIONS = {
  title: "", // 标题
  value: undefined, // 当前值
  format: 'YYYY-MM-DD HH:mm', // 默认格式
};
export default {
  name: "HanDateTime",

  data() {
    return {
      show: false,
      // formats: DATE_FORMAT.concat(TIME_FORMAT),
      columns: [],
      fieldKeys: [],
      options: {
        ...DEFAULT_OPTIONS,
      },
    };
  },

  computed: {},

  methods: {
    init(options = {}) {
      this.show = true;

      this.options = {
        ...DEFAULT_OPTIONS,
        ...options,
      };

      // if (!this.formats.includes(this.options.format)) {
      //   return;
      // }

      this.initColumns();
    },

    /**
     * 初始化年份数据
     */
    initYear(year) {
      const yearValues = Array(300)
        .fill("")
        .map((item, index) => String(year - 200 + index));
      const yearIndex = yearValues.findIndex((item) => item === year);
      return {
        values: yearValues,
        defaultIndex: yearIndex,
      };
    },

    /**
     * 初始化月数据
     */
    initMonth(month) {
      const monthValues = Array(12)
        .fill("")
        .map((item, index) => String(index + 1).padStart(2, "0"));
      const monthIndex = Number(month) - 1;
      return {
        values: monthValues,
        defaultIndex: monthIndex,
      };
    },

    /**
     * 初始化日期数据
     * 根据年月初始化日期列表
     */
    initDate(date, year = "", month = "") {
      let length = 30;
      if (!month) {
        // 不指定月份  默认31
        length = 31;
      } else {
        const nMonth = Number(month);
        if ([1, 3, 5, 7, 8, 10, 12].includes(nMonth)) {
          length = 31;
        } else if (nMonth === 2) {
          if ((year && Dayjs(new Date(year, 1, 1)).isLeapYear()) || !year) {
            // 不指定年份 或者 闰年
            length = 29;
          } else {
            length = 28;
          }
        }
      }

      const dateValues = Array(length)
        .fill("")
        .map((item, index) => String(index + 1).padStart(2, "0"));
      const dateIndex = Number(date) - 1;
      return {
        values: dateValues,
        defaultIndex: dateIndex > length ? length : dateIndex,
      };
    },

    /**
     * 初始化时分秒数据
     */
    initHHmmss(value, length) {
      const values = Array(length)
        .fill("")
        .map((item, index) => String(index).padStart(2, "0"));
      const index = Number(value);
      return {
        values: values,
        defaultIndex: index,
      };
    },

    initColumns() {
      const { format, value } = this.options;
      const validVal = value || Dayjs().format(format); // 默认设置为当前日期
      const fieldKeys = format.match(/[a-zA-Z]+/g);
      const fieldVals = validVal.match(/[0-9]+/g);

      const columns = [];
      fieldKeys.forEach((field, index) => {
        const fieldVal = fieldVals[index];
        switch (field) {
          case "YYYY":
            columns.push(this.initYear(fieldVal));
            break;
          case "MM":
            columns.push(this.initMonth(fieldVal));
            break;
          case "DD":
            (() => {
              const yearIndex = fieldKeys.findIndex((e) => e === "YYYY");
              const yearValue = yearIndex < 0 ? "" : fieldVal[yearIndex];
              const monthIndex = fieldKeys.findIndex((e) => e === "MM");
              const monthValue = yearIndex < 0 ? "" : fieldVal[monthIndex];
              columns.push(this.initDate(fieldVal, yearValue, monthValue));
            })();
            break;
          case "HH":
            columns.push(this.initHHmmss(fieldVal, 24));
            break;
          case "mm":
            columns.push(this.initHHmmss(fieldVal, 60));
            break;
          case "ss":
            columns.push(this.initHHmmss(fieldVal, 60));
            break;
        }
      });
      this.fieldKeys = fieldKeys;
      this.columns = columns;
    },

    async onChange(picker, value, index) {
      const fieldKey = this.fieldKeys[index];
      const dateIndex = this.fieldKeys.findIndex((key) => key === "DD");
      if (dateIndex < 0) {
        //不包含日期数据
        return;
      }

      if (!["YYYY", "MM"].includes(fieldKey)) {
        // 变更字段非年月
        return;
      }
      const yearIndex = this.fieldKeys.findIndex((key) => key === "YYYY");
      const monthIndex = this.fieldKeys.findIndex((key) => key === "MM");
      const yearValue = picker.getColumnValue(yearIndex);
      const monthValue = picker.getColumnValue(monthIndex);
      const dateValue = picker.getColumnValue(dateIndex);

      // 获取最新的日期数据并更新
      const dateColumn = this.initDate(dateValue, yearValue, monthValue);
      this.$set(this.columns, dateIndex, dateColumn);
    },

    onCancel() {
      this.show = false;
    },

    onConfirm(value) {
      let result = this.options.format;
      let fieldKeys = this.fieldKeys;
      value.forEach((item, index) => {
        result = result.replace(fieldKeys[index], item);
      });
      const { onConfirm } = this.options;
      onConfirm(result)
      this.show = false
    },
  },
};
</script>

<style lang="less" scoped></style>
